package br.com.educa.util;

import java.util.*;
import java.lang.reflect.*;

public class ConvertUtil {
	
	private static Map<Class, Class> primitiveMap = new HashMap<Class, Class>();
	static {
		primitiveMap.put(boolean.class, Boolean.class);
		primitiveMap.put(byte.class, Byte.class);
		primitiveMap.put(char.class, Character.class);
		primitiveMap.put(short.class, Short.class);
		primitiveMap.put(int.class, Integer.class);
		primitiveMap.put(long.class, Long.class);
		primitiveMap.put(float.class, Float.class);
		primitiveMap.put(double.class, Double.class);
	}

	/**
	 * Best try to convert string to destination class. If destClass is one of
	 * the supported primitive classes, an object of that type is returned.
	 * Otherwise, the original string is returned.
	 */
	public static Object convert(String value, Class<?> destClass) {
		if ((value == null) || "".equals(value)) {
			return value;
		}

		if (destClass.isPrimitive()) {
			destClass = primitiveMap.get(destClass);
		}

		try {
			Method m = destClass.getMethod("valueOf", String.class);
			int mods = m.getModifiers();
			if (Modifier.isStatic(mods) && Modifier.isPublic(mods)) {
				return m.invoke(null, value);
			}
		} catch (NoSuchMethodException e) {
			if (destClass == Character.class) {
				return Character.valueOf(value.charAt(0));
			}
		} catch (IllegalAccessException e) {
			// this won't happen
		} catch (InvocationTargetException e) {
			// when this happens, the string cannot be converted to the intended
			// type
			// we are ignoring it here - the original string will be returned.
			// But it can be re-thrown if desired!
		}

		return value;
	}

	public static void main(String[] args) throws ClassNotFoundException {
		System.out.printf("Convert to boolean: %s, %s\n", "true", ConvertUtil
				.convert("true", boolean.class).getClass().getName());
		System.out.printf("Convert to byte: %s, %s\n", "12", ConvertUtil
				.convert("12", Byte.class).getClass().getName());
		System.out.printf("Convert to char: %s, %s\n", "hello", ConvertUtil
				.convert("hello", Character.class).getClass().getName());
		System.out.printf("Convert to short: %s, %s\n", "34", ConvertUtil
				.convert("34", short.class).getClass().getName());
		System.out.printf("Convert to int: %s, %s\n", "90123456", ConvertUtil
				.convert("90123456", int.class).getClass().getName());
		System.out.printf("Convert to long: %s, %s\n", "current time",
				ConvertUtil
						.convert("" + System.currentTimeMillis(), Long.class)
						.getClass().getName());
		System.out.printf("Convert to float: %s, %s\n", "12.34", ConvertUtil
				.convert("12.34", Float.class).getClass().getName());
		System.out.printf(
				"Convert to double: %s, %s\n",
				"3512895.435423",
				ConvertUtil
						.convert("3512895.435423",
								Class.forName("java.lang.Double")).getClass()
						.getName());
	}
}